# Copyright (c) 2020 cgsdfc
# 
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT

project(pyast CXX)

cmake_minimum_required(VERSION 3.10)

find_package(pybind11 REQUIRED)

option(PYAST_BUILD_TEST "Whether to build the test" OFF)

# TODO: Fix this.
if(PYAST_BUILD_TEST)
  find_package(GTest REQUIRED)
endif()

file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" PYAST_VERSION)
message(STATUS "pyast version: ${PYAST_VERSION}")

macro(find_python_package package_name variable version_variable)
  if(NOT ${variable})
    execute_process(
      COMMAND
        ${PYTHON_EXECUTABLE} -c
        "import ${package_name}; print(${package_name}.__version__, end='')"
      RESULT_VARIABLE not_found
      OUTPUT_VARIABLE version
      ERROR_QUIET)
    if(not_found)
      message(
        FATAL_ERROR
          "${PROJECT_NAME} requires ${package_name}. Please install it manually"
          " (try: ${PYTHON_EXECUTABLE} -m pip install ${package_name})")
    else()
      set(${version_variable} ${version})
      message(STATUS "Found ${package_name} version: ${version}")
    endif()
    set(${variable}
        TRUE
        CACHE INTERNAL "")
  endif()
endmacro(find_python_package)

find_python_package(mako PYAST_MAKO_FOUND PYAST_MAKO_VERSION)
find_python_package(pycparser PYAST_PYCPARSER_FOUND PYAST_PYCPARSER_VERSION)

set(PYAST_GEN_DIR ${CMAKE_BINARY_DIR})

add_custom_command(
    OUTPUT pp_out.h
    COMMAND PYTHONPATH=${CMAKE_SOURCE_DIR} ${PYTHON_EXECUTABLE} -m astlib.gen_hdr
    -i ${PYTHON_INCLUDE_DIR} -o pp_out.h
    DEPENDS
        astlib/gen_hdr.py
    WORKING_DIRECTORY ${PYAST_GEN_DIR} 
)

add_custom_command(
    OUTPUT Python.asdl
    COMMAND PYTHONPATH=${CMAKE_SOURCE_DIR}  ${PYTHON_EXECUTABLE} -m astlib.gen_asdl -i pp_out.h -o Python.asdl
    DEPENDS
        astlib/asdl.py
        astlib/asdl_index.py
        astlib/asdl_unparse.py
        astlib/gen_asdl.py
        astlib/license_const.py
        pp_out.h

    WORKING_DIRECTORY ${PYAST_GEN_DIR} 
)

add_custom_command(
    OUTPUT data.pkl
    COMMAND PYTHONPATH=${CMAKE_SOURCE_DIR}  ${PYTHON_EXECUTABLE} -m astlib.gen_data -i Python.asdl -o data.pkl
    DEPENDS
        astlib/asdl.py
        astlib/cc_types.py
        astlib/gen_data.py
        Python.asdl

    WORKING_DIRECTORY ${PYAST_GEN_DIR} 
)

function(generate_source output)
  set(template_file ${CMAKE_SOURCE_DIR}/${output}.mako)

    add_custom_command(
        OUTPUT ${output}

        COMMAND PYTHONPATH=${CMAKE_SOURCE_DIR} ${PYTHON_EXECUTABLE} -m astlib.gen_src
        -t ${template_file} -o ${output} --data data.pkl

        DEPENDS 
            astlib/cc_types.py
            astlib/format_utils.py
            astlib/gen_src.py
            astlib/mako_utils.py
        
            ${template_file}
            data.pkl

        WORKING_DIRECTORY ${PYAST_GEN_DIR} 
    )

endfunction()

generate_source(pyast/ast.h)
generate_source(pyast/ast.cc)
generate_source(pyast/undefs.h)
generate_source(pyast/config.h)

add_library(
    pyast
    pyast/arena.h
    pyast/asdl_seq.h
    pyast/ast.cc
    pyast/ast.h
    pyast/ast_node.h
    pyast/config.h
    pyast/location.h
    pyast/logging.h
    pyast/pyast.h
    pyast/pybind_defs.h
    pyast/undefs.h
)

target_include_directories(pyast PUBLIC ${PYAST_GEN_DIR} ${CMAKE_SOURCE_DIR})

target_link_libraries(pyast pybind11::module ${PYTHON_LIBRARIES})

if (PYAST_BUILD_TEST)
    add_executable(
        pyast_test
        pyast/testing.cc
        pyast/list_test.cc
        pyast/arena_test.cc 
    )
    target_link_libraries(pyast_test pybind11::embed gtest_main)
endif()

add_library(
    pydsl
    pydsl/pydsl.h
    pydsl/pydsl.cc
)

target_link_libraries(
    pydsl
    pyast
)

add_executable(pydsl_test pydsl/pydsl_test.cc)

target_link_libraries(pydsl_test pydsl pybind11::embed)

# include(GNUInstallDirs) install(FILES ${PYAST_PUBLIC_HEADER} DESTINATION
# ${CMAKE_INSTALL_INCLUDEDIR}/pyast) install(TARGETS pyast ARCHIVE DESTINATION
# ${CMAKE_INSTALL_LIBDIR}) install(FILES ${PYAST_DATA_DIR}/Python.asdl
# DESTINATION ${CMAKE_INSTALL_DATADIR}/pyast)
